package com.example.administrator.chesstest01;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2016/6/25.
 */
public class MyView extends View {

    private  int mPanelWidth;
    private float mLineHeoht;
    private  int MAX_LINE = 10;
    private MyService.OptBinder binder ;
    private Paint mPaint = new Paint();//用于画棋盘
    private Bitmap mWhitePiece;//黑棋子
    private Bitmap mBlackPiece;//白棋子
    //棋子的长度和高度
    private float ratioPieceOfLineHeight = 3 * 1.0f / 4;
    //棋子的坐标
    private boolean isWhiteSelf;
    private boolean mIsWhite = true;//白棋先手，当前轮到白棋子了
    private ArrayList<Point> mWhiteArray = new ArrayList<>();//棋子
    private ArrayList<Point> mBlackArray = new ArrayList<>();
    //判断 谁赢
    private boolean mIsGameOver;
    private boolean mIsWhitew;

    int MAX_COUNT_INLINE = 5;

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setBackgroundColor(0x44ff0000);//设置背景
        init();
    }
    public void setData(String data){
        AnalysisJson.ReceiveChessMessage(data,mWhiteArray,mBlackArray);
        mIsWhite = !mIsWhite;
        invalidate();
    }
    //棋盘初始化
    private  void init(){//设置棋盘类型
        mPaint.setColor(0x88000000);//设置背景半透明
        mPaint.setAntiAlias(true);//抗锯齿
        mPaint.setDither(true);//抖动
        mPaint.setStyle(Paint.Style.STROKE);//风格
        //把棋子导入
        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.s2);
        mBlackPiece = BitmapFactory.decodeResource(getResources(),R.drawable.s1);
    }

    @Override//测量
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);//获得最大的宽度
        int widthMod = MeasureSpec.getMode(widthMeasureSpec);//获得宽度


        int heightSize = MeasureSpec.getSize(heightMeasureSpec);//获得最大的高度
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);//获得高度

        //精确地值
        int width = Math.min(widthSize,heightSize);//最小值
        if(widthMod ==MeasureSpec.UNSPECIFIED){//如果宽度没设置的话 就有高度决定
            width = heightSize;
        }else if (heightMode==MeasureSpec.UNSPECIFIED){//如果高度没设置的话 就有宽度决定
            width = widthSize;
        }
        setMeasuredDimension(width,width);//宽高设置同样的值
    }

    @Override//宽高发生改变 的时候会回调
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mPanelWidth = w;//得到行高
        mLineHeoht = mPanelWidth * 1.0f /MAX_LINE;//得到行高

        //设置棋子的大小
        int piexceWidth = (int) (mLineHeoht*ratioPieceOfLineHeight);//设置高宽度
        mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece,piexceWidth,piexceWidth,false);//设置白棋子的宽度和高度
        mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece,piexceWidth,piexceWidth,false);//设置黑棋子的宽度和高度
    }

    public void setBinder(MyService.OptBinder binder){
        this.binder = binder;
    }
    @Override//触摸事件
    public boolean onTouchEvent(MotionEvent event) {

        if (mIsGameOver) return false;
        if (mIsWhite != isWhiteSelf){
            return false;
        }
        int action = event.getAction();
        if (action==MotionEvent.ACTION_UP){
            int x = (int) event.getX();
            int y = (int) event.getY();
            Point p = getValidPoint(x,y);
            if (mWhiteArray.contains(p)||mBlackArray.contains(p)){
                return false;
            }
            if (mIsWhite){
                mWhiteArray.add(p);
            }else {
                mBlackArray.add(p);
            }
            invalidate();
            mIsWhite = !mIsWhite;
            AnalysisJson.SendChessMessage("123",binder,mWhiteArray,mBlackArray);
            System.out.println("--------------mWhiteArray="+mWhiteArray.toString());
            System.out.println("--------------mBlackArray="+mBlackArray.toString());
            return true;
        }
        return true;
    }

    private Point getValidPoint(int x, int y) {
        return new Point((int) (x/mLineHeoht),(int) (y/mLineHeoht));
    }

    @Override// 设置棋盘
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBoard(canvas);//绘制棋盘
        drawPieces(canvas);//绘制棋子
        checkGameOver();//游戏结束判断
    }

    private void checkGameOver() {
        boolean whireWin= checkFiveInLine(mWhiteArray);
        boolean blackWin= checkFiveInLine(mBlackArray);
        if (whireWin||blackWin){
            mIsGameOver = true;
            mIsWhitew = whireWin;
            String text = mIsWhitew ? "白棋赢":"黑棋赢";
            Toast.makeText(getContext(),text,Toast.LENGTH_SHORT).show();
        }
    }

    private boolean checkFiveInLine(List<Point> points) {

        for (Point p:points){
            int x= p.x;
            int y =p.y;
            boolean win=  checkHorizontal(x,y,points);
            if (win)return true;
            win=checkHorizontal(x,y,points);
            if (win)return true;
            win=checkVertical(x,y,points);
            if (win)return true;
            win= checkLeftDiagonal(x,y,points);
            if (win)return true;
            win=checkRightDiagonal(x,y,points);
            if (win)return true;
        }
        return false;
    }

    /**
     * 判断x,y位子的棋子是否有相邻的五个一致。
     * @param x
     * @param y
     * @param points
     * @return
     */
    private boolean checkHorizontal(int x, int y, List<Point> points) {
        int count = 1;
        //横向左边
        for (int i=1;i<MAX_COUNT_INLINE;i++){
            if (points.contains(new Point(x-i,y))){
                count++;
            }else {
                break;
            }
        }
        for (int i=1;i<MAX_COUNT_INLINE;i++){
            if (points.contains(new Point(x+i,y))){
                count++;
            }else {
                break;
            }
        }
        if (count==5){
            return true;
        }
        return false;
    }
    private boolean checkVertical(int x, int y, List<Point> points) {
        int count = 1;
        //上下
        for (int i=1;i<MAX_COUNT_INLINE;i++){
            if (points.contains(new Point(x,y-i))){
                count++;
            }else {
                break;
            }
        }
        for (int i=1;i<MAX_COUNT_INLINE;i++){
            if (points.contains(new Point(x,y+i))){
                count++;
            }else {
                break;
            }
        }
        if (count==5){
            return true;
        }
        return false;

    }

    private boolean checkLeftDiagonal(int x, int y, List<Point> points) {
        int count = 1;
        //左斜
        for (int i=1;i<MAX_COUNT_INLINE;i++){
            if (points.contains(new Point(x-i,y+i))){
                count++;
            }else {
                break;
            }
        }
        for (int i=1;i<MAX_COUNT_INLINE;i++){
            if (points.contains(new Point(x+i,y-i))){
                count++;
            }else {
                break;
            }
        }
        if (count==5){
            return true;
        }
        return false;

    }
    private boolean checkRightDiagonal(int x, int y, List<Point> points) {
        int count = 1;
        //右斜
        for (int i=1;i<MAX_COUNT_INLINE;i++){
            if (points.contains(new Point(x-i,y-i))){
                count++;
            }else {
                break;
            }
        }
        for (int i=1;i<MAX_COUNT_INLINE;i++){
            if (points.contains(new Point(x+i,y+i))){
                count++;
            }else {
                break;
            }
        }
        if (count==5){
            return true;
        }
        return false;

    }


    private void drawPieces(Canvas canvas) {//设置落字

        for (int i =0;i<mWhiteArray.size();i++){
            Point whitePoint = mWhiteArray.get(i);
            canvas.drawBitmap(mWhitePiece,
                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeoht,
                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeoht,null);
        }
        for (int i =0;i<mBlackArray.size();i++){
            Point blackPoint = mBlackArray.get(i);
            canvas.drawBitmap(mBlackPiece,
                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeoht,
                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeoht,null);
        }

    }

    private void drawBoard(Canvas canvas) {
        int w = mPanelWidth;//棋盘的宽度
        float lineHeight = mLineHeoht;//行的高度

        for (int i =0 ; i<MAX_LINE;i++){//绘制横线
            int startX = (int) (lineHeight/2);//起点
            int endX = (int) (w-lineHeight/2);//终点

            int y = (int) ((0.5+i)*lineHeight);//坐标
            canvas.drawLine(startX,y,endX,y,mPaint);//开始划线
            canvas.drawLine(y,startX,y,endX,mPaint);

        }
    }
    public void start(boolean isWhiteSelf){
        this.isWhiteSelf = isWhiteSelf;
        mWhiteArray.clear();
        mBlackArray.clear();
        mIsGameOver =false;
        mIsWhitew=false;
        invalidate();
    }

    private static final String INSTANCE = "instance";
    private static final String INSTANCE_GAME_OVER ="instance_game_over";
    private static final String INSTANCE_WHITE_ARRAY ="instance_game_over";
    private static final String INSTANCE_BLACK_ARRAY ="instance_game_over";
    @Override
    protected Parcelable onSaveInstanceState() {
        Bundle bundle = new Bundle();
        bundle.putParcelable(INSTANCE,super.onSaveInstanceState());
        bundle.putBoolean(INSTANCE_GAME_OVER,mIsGameOver);
        bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY,mWhiteArray);
        return bundle;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {

        if (state instanceof Bundle){
            Bundle bundle = (Bundle) state;
            mIsGameOver = bundle.getBoolean(INSTANCE_GAME_OVER);
            mWhiteArray = bundle.getParcelableArrayList(INSTANCE_WHITE_ARRAY);
            mBlackArray = bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);
            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE));
            return;
        }
        super.onRestoreInstanceState(state);
    }
}

